#ifndef _EXPRESSAO_H
#define _EXPRESSAO_H

using namespace std;

class Context{
	  double variaveis[26][2];
	public:
	  Context();
	  void inserir(char c, double num);
	  double get(char c);
};

class VariableExp;

class Expressao{
	public:
	virtual double avalia(Context& c)=0;
};

//Expressoes logicas

//Derivaçao generica das exp logicas
class logica_exp: public Expressao{
	public:
		virtual double avalia(Context& c) = 0;
};	

class And: public logica_exp{
	public:
		And(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		//Guarda as expressoes para avaliar mais tarde
		Expressao *um, *dois;
};

class Or: public logica_exp{
	public:
		Or(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		//Guarda as expressoes para avaliar mais tarde
		Expressao *um, *dois;
};	

//derivação generica para exp de comparação

class exp_comp: public Expressao{
	public:
		virtual double avalia(Context &c)=0;
};	

class Equals: public exp_comp{
	public:
		Equals(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		//guarda as expressoes para avaliar mais tarde
		Expressao *um, *dois;
};	

class Geq: public exp_comp{
	public:
		Geq(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		//guarda as expressoes para avaliar mais tarde
		Expressao *um, *dois;

};

class Leq: public exp_comp{
	public:
		Leq(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		//guarda as expressoes para avaliar mais tarde
		Expressao *um, *dois;
};	

class Less: public exp_comp{
	public: 
		Less(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private: 
		//guarda as expressoes para avaliar mais tarde
		Expressao *um, *dois;	
};	

class Greater: public exp_comp{
	public: 
		Greater(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private: 
		//guarda as expressoes para avaliar mais tarde
		Expressao *um, *dois;	
};	


// Inicio das expressoes aritimeticas

//Derivação generica de expressao aritimetica
class exp_arit: public Expressao{
	public:
		virtual double avalia(Context &c)=0;
};	

class Sum: public exp_arit{
	public:
		Sum(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		Expressao *um, *dois;
};	

class Sub: public exp_arit{
	public:
		Sub(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		Expressao *um, *dois;
};	

class Mult: public exp_arit{
	public:
		Mult(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		Expressao *um, *dois;
};	

class Div: public exp_arit{
	public:
		Div(Expressao *um, Expressao *dois);
		virtual double avalia(Context &c);
	private:
		Expressao *um, *dois;
};	

class Sqrt: public exp_arit{
	public:
		Sqrt(Expressao *um);
		virtual	double avalia(Context &c);
	private:
		Expressao *um;
};	

class Valor: public Expressao{
	public:
		Valor(double v);
		Valor(char c);
		virtual double avalia(Context &c);
	private:
		bool val_or_var; //0=valor 1=variavel
		double valor;
		char variavel;
};	

#endif
